package com.jvyou.app.common.utils.value;

import java.util.Collection;

/**
 * 值工具类
 *
 * @author 橘柚
 * @since 2024/9/10 11:43
 */
public class ValueUtil {


    /**
     * 判断数字类型是否为空，为空时返回 true
     *
     * @param number 待判断的数字
     * @param <T>    数字的类型
     * @return 是否为 null 或者 0
     */
    public static <T extends Number> boolean isZero(T number) {
        return number == null || number.doubleValue() == 0;
    }

    /**
     * 数字为空时执行回调
     *
     * @param number   待判断的数字
     * @param callback 回调函数
     * @param <T>      数字的类型
     */
    public static <T extends Number> void ifZero(T number, Runnable callback) {
        if (isZero(number)) {
            callback.run();
        }
    }

    /**
     * 拼接两个字符串，使用指定的符号作为分隔符。
     * 如果任一字符串为空，则直接返回非空字符串；如果两者都为空，则返回空字符串。
     *
     * @param str1      第一个字符串
     * @param str2      第二个字符串
     * @param delimiter 分隔符
     * @return 拼接结果
     */
    public static String joinWithDelimiter(String str1, String str2, String delimiter) {
        // 默认分隔符为空字符串以防止传入 null
        if (delimiter == null) {
            delimiter = "";
        }

        // 两个都为空返回空字符串
        if ((str1 == null || str1.isEmpty()) && (str2 == null || str2.isEmpty())) {
            return "";
        }

        // 如果其中一个为空，返回非空的那个
        if (str1 == null || str1.isEmpty()) {
            return str2;
        }
        if (str2 == null || str2.isEmpty()) {
            return str1;
        }

        // 两个都不为空，使用分隔符拼接
        return str1 + delimiter + str2;
    }

    /**
     * 判断给定的值是否为空。
     * 该方法通过检查值是否为 {@code null} 来实现。
     *
     * @param <T>   值的类型
     * @param value 要检查的值
     * @return 如果值为空（即 {@code null}），则返回 {@code true}；否则返回 {@code false}
     */
    public static <T> boolean isNull(T value) {
        return value == null;
    }

    /**
     * 当给定的值为空时，执行指定的回调操作。
     * 该方法首先调用 {@link #isNull(Object)} 方法检查值是否为空，
     * 如果值为空，则执行传入的 {@link Runnable} 回调。
     *
     * @param <T>      值的类型
     * @param value    要检查的值
     * @param callback 值为空时要执行的回调操作
     */
    public static <T> void isNull(T value, Runnable callback) {
        if (isNull(value)) {
            callback.run();
        }
    }

    /**
     * 判断给定的数字是否不为空且不为0。
     * 该方法通过调用 {@link #isZero(Number)} 方法并取反来实现。
     *
     * @param <T>    数字的类型，必须是 {@link Number} 的子类
     * @param number 要检查的数字
     * @return 如果数字不为空且不为0，则返回 {@code true}；否则返回 {@code false}
     */
    public static <T extends Number> boolean isNotZero(T number) {
        return !isZero(number);
    }

    /**
     * 当给定的数字不为空且不为0时，执行指定的回调操作。
     * 该方法首先调用 {@link #isZero(Number)} 方法检查数字是否为0，
     * 如果数字不为0，则执行传入的 {@link Runnable} 回调。
     *
     * @param <T>      数字的类型，必须是 {@link Number} 的子类
     * @param number   要检查的数字
     * @param callback 数字不为空且不为0时要执行的回调操作
     */
    public static <T extends Number> void ifNotZero(T number, Runnable callback) {
        if (isZero(number)) {
            callback.run();
        }
    }

    /**
     * 判断 tValue 是否为空或解析为 double 为 0
     *
     * @param tValue 字符串形式的值
     * @return 如果 tValue 为空或解析为 double 为 0，返回 true；否则返回 false
     */
    public static boolean isEmptyOrZero(String tValue) {
        if (tValue == null || tValue.trim().isEmpty()) {
            return true;
        }
        try {
            double value = Double.parseDouble(tValue.trim());
            return value == 0.0;
        } catch (NumberFormatException e) {
            // 如果无法解析为 double，视为非 0
            return false;
        }
    }

    /**
     * 判断给定的值是否不为空。
     * 该方法通过调用 {@link #isNull(Object)} 方法并取反来实现。
     *
     * @param <T>   值的类型
     * @param value 要检查的值
     * @return 如果值不为空，则返回 {@code true}；否则返回 {@code false}
     */
    public static <T> boolean isNotNull(T value) {
        return !isNull(value);
    }

    /**
     * 当给定的值不为空时，执行指定的回调操作。
     * 该方法首先调用 {@link #isNotNull(Object)} 方法检查值是否为空，
     * 如果值不为空，则执行传入的 {@link Runnable} 回调。
     *
     * @param <T>      值的类型
     * @param value    要检查的值
     * @param callback 值不为空时要执行的回调操作
     */
    public static <T> void isNotNull(T value, Runnable callback) {
        if (isNotNull(value)) {
            callback.run();
        }
    }

    /**
     * 判断字符串是否为空
     *
     * @param str 待判断的字符串
     * @return 是否为 null 或者 ""
     */
    public static boolean isEmpty(String str) {
        return str == null || str.trim().isEmpty() || str.trim().equalsIgnoreCase("null");
    }

    /**
     * 字符串为空时执行回调
     *
     * @param str      待判断的字符串
     * @param callback 回调函数
     */
    public static void isEmpty(String str, Runnable callback) {
        if (isEmpty(str)) {
            callback.run();
        }
    }

    /**
     * 判断集合是否为空
     *
     * @param collection 待判断的集合
     * @return 是否为 null 或者空集合
     */
    public static boolean isEmpty(Collection<?> collection) {
        return collection == null || collection.isEmpty();
    }


    /**
     * 字符串为空时执行回调
     *
     * @param str           待判断的字符串
     * @param trueCallback  条件成立回调函数
     * @param falseCallback 条件不成立回调函数
     */
    public static void isEmptyOrElse(String str, Runnable trueCallback, Runnable falseCallback) {
        if (isEmpty(str)) {
            trueCallback.run();
        } else {
            falseCallback.run();
        }
    }

    /**
     * 判断字符串是否不为空
     *
     * @param str 待判断的字符串
     * @return 是否不为 null 或者 ""
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    /**
     * 字符串不为空时执行回调
     *
     * @param str      待判断的字符串
     * @param callback 回调函数
     */
    public static void isNotEmpty(String str, Runnable callback) {
        if (isNotEmpty(str)) {
            callback.run();
        }
    }

    /**
     * 不为空等值判断
     *
     * @param str  待判断的字符串1
     * @param str2 待判断的字符串2
     */
    public static boolean notEmptyEq(String str, String str2) {
        return !isEmpty(str) && !isEmpty(str2) && str.equals(str2);
    }


    /**
     * 判断字符串是否为空，为空时返回默认值
     *
     * @param str          待判断的字符串
     * @param defaultValue 默认值
     * @return 默认值或者原值
     */
    public static String isEmpty(String str, String defaultValue) {
        return isEmpty(str) ? defaultValue : str;
    }


    public static class DefaultValueProvider {
        private final String defaultValue;

        private DefaultValueProvider(String defaultValue) {
            this.defaultValue = defaultValue;
        }

        /**
         * 判断字符串是否为空，为空时返回默认值
         *
         * @param str 待判断的字符串
         * @return 默认值或者原值
         */
        public String defaultVal(String str) {
            return ValueUtil.isEmpty(str, defaultValue);
        }
    }

    public static DefaultValueProvider defaultValueProvider(String defaultValue) {
        return new DefaultValueProvider(defaultValue);
    }

    /**
     * 拼接不定个字符串，使用指定的连接符，如果全部都为空则返回默认的值。
     *
     * @param defaultValue 如果所有输入字符串为空时，返回的默认值
     * @param separator    连接符
     * @param strings      要拼接的字符串
     * @return 拼接后的字符串或默认值
     */
    public static String concatOrDefault(String defaultValue, String separator, String... strings) {
        // 检查是否所有字符串都为空
        boolean allEmpty = true;

        // 拼接非空的字符串
        StringBuilder result = new StringBuilder();
        for (String str : strings) {
            if (str != null && !str.trim().isEmpty()) {
                if (result.length() > 0) {
                    result.append(separator);  // 添加连接符
                }
                result.append(str);  // 拼接非空字符串
                allEmpty = false;
            }
        }

        // 如果所有字符串都为空，则返回默认值
        return allEmpty ? defaultValue : result.toString();
    }

}
